#pragma once
#include <iostream>
#include <memory>
#include <dirent.h>
#include <sys/stat.h>
#include "retinaface_det_api.h"
#include <algorithm>
#include <chrono>
#include <vector>
#include <opencv2/opencv.hpp>
using namespace retinaface;

int64_t CurrentTimeMillis()
{
    int64_t timems = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count();
    return timems;
}
void FindFiles(const std::string &path, std::vector<std::string> &files)
{
    struct stat rst;
    if (stat(const_cast<char *>(path.c_str()), &rst) != 0)
        return;
    DIR *dirpt = opendir(path.data());
    dirent *entry;
    while (entry = readdir(dirpt))
    {
        /* code */
        if (entry->d_type == DT_REG)
            files.emplace_back(entry->d_name);
    }
    closedir(dirpt);
}

void PrintVector(const std::vector<float> vec)
{

    for (auto iter = vec.cbegin(); iter != vec.cend(); iter++)
    {
        std::cout << (*iter) << " ";
    }
}

void test_retinaface()
{

    std::shared_ptr<RetinaFaceApi> retinaface_gpu = std::make_shared<RetinaFaceApi>(0,
                                                                                    "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/retinaface_mobilenet/FaceDetector_sim.onnx",
                                                                                    "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model/");

    // std::string file_path = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize.jpg";
    // std::string file_path = "/home/user/yyz_workspace_disk/Code/face/Pytorch_Retinaface-master/curve/test.jpg";
    // std::string file_path = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize_320.jpg";
    std::string file_path = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize_1024.jpg";

    cv::Mat img = cv::imread(file_path);
    std::vector<cv::Rect> rectangles;
    std::vector<float> confidence;
    std::vector<std::vector<cv::Point>> landmarks;

    retinaface_gpu->Execute(img, rectangles, confidence, landmarks);

    for (int i = 0; i < rectangles.size(); i++)
    {
        cv::rectangle(img, rectangles[i], cv::Scalar(255, 0, 255), 1);
        for (size_t j = 0; j < 5; j++)
        {
            cv::circle(img, landmarks[i][j], 1,
                       cv::Scalar(0, 255, 0), 1);
        }
        cv::putText(img, std::to_string(confidence[i]),
                    cv::Point(rectangles[i].x + 3, rectangles[i].y - 4), 1, 1,
                    cv::Scalar(255, 255, 0));
    }
    // cv::resize(img, img, cv::Size(0, 0), 0.7, 0.7);
    cv::imshow("img", img);
    cv::waitKey();
}

void test_batch_retinaface()
{

    std::shared_ptr<RetinaFaceApi> retinaface_gpu = std::make_shared<RetinaFaceApi>(0,
                                                                                    "/home/user/yyz_workspace_disk/Code/algolib/input_models/onnx_model/retinaface_mobilenet/FaceDetector_dynamic.onnx",
                                                                                    "/home/user/yyz_workspace_disk/Code/algolib/input_models/trt_model/",
                                                                                    8);

    // std::string file_path = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize.jpg";
    // std::string file_path = "/home/user/yyz_workspace_disk/Code/face/Pytorch_Retinaface-master/curve/test.jpg";
    std::string file_path0 = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize_320.jpg";
    std::string file_path1 = "/bata/Code/face/Pytorch_Retinaface-master/curve/test_resize_1024.jpg";

    cv::Mat img0 = cv::imread(file_path0);
    cv::Mat img1 = cv::imread(file_path1);

    std::vector<cv::Mat> mat_vec;
    mat_vec.emplace_back(img0);
    mat_vec.emplace_back(img1);

    std::vector<std::vector<cv::Rect>> rectangles;
    std::vector<std::vector<float>> confidence;
    std::vector<std::vector<std::vector<cv::Point>>> landmarks;

    retinaface_gpu->Execute(mat_vec, rectangles, confidence, landmarks);

    for (int k = 0; k < mat_vec.size(); k++)
    {
        for (int i = 0; i < rectangles[k].size(); i++)
        {
            cv::rectangle(mat_vec[k], rectangles[k][i], cv::Scalar(255, 0, 255), 1);
            for (size_t j = 0; j < 5; j++)
            {
                cv::circle(mat_vec[k], landmarks[k][i][j], 1, cv::Scalar(0, 255, 0), 1);
            }
            cv::putText(mat_vec[k], std::to_string(confidence[k][i]), cv::Point(rectangles[k][i].x + 3, rectangles[k][i].y - 4), 1, 1, cv::Scalar(255, 255, 0));
        }
        // cv::resize(mat_vec[k], mat_vec[k], cv::Size(0, 0), 0.8, 0.8);
        cv::imshow("img" + std::to_string(k), mat_vec[k]);
        cv::imwrite("../output_images/img" + std::to_string(k) + ".jpg", mat_vec[k]);
    }
    cv::waitKey();
};